#pragma once

/**
 * This can be used for testing when a global function needs to be replaced with
 * a test double temporarily. In the test you create an instance of the class
 * that is automatically deleted after the test (when the variable goes out of
 * scope). Creating the instance sets the value and destroying it resets it so
 * the state after the test is the same as before.
 * Here is an example usage, replacing OpenGL's glCreateProgram function with
 * myCreateProgramReplacement temporarily:
 *
 * void test() {
 *   TemporaryAssignerAndResetter < decltype(glCreateProgram) > t(
 *     &glCreateProgram,
 *     &myCreateProgramReplacement);
 *   // ... do the tests that are calling glCreateProgram
 * }
 */
template<class T>
class TemporaryAssignerAndResetter {
public:

    TemporaryAssignerAndResetter(T* pointerToPointer, T assignToThisTemporarily) {
        original = *pointerToPointer;
        pointerToReset = pointerToPointer;
        *pointerToReset = assignToThisTemporarily;
    }

    ~TemporaryAssignerAndResetter() {
        *pointerToReset = original;
    }

private:
    T original;
    T* pointerToReset;
};